module vga(
	input 				clk,	//clk
	input 				rst_n,
    input	     		start_send,
	input  		[4:0]	num,

    output 	reg			one_frame_end,
	output  			hsyn,
	output  			vsyn,
	output 				de,
	output  reg [23:0] 	dout
);
//this is for 640*480 
parameter H_ACTIVE		=		640;
parameter H_FRONT_PROCH	=		16;
parameter H_BACK_PROCH	=		48;
parameter H_SYN			=		96;
parameter H_TOTAL		=		H_ACTIVE+H_SYN+H_BACK_PROCH+H_FRONT_PROCH;//800

parameter V_ACTIVE		=		480;
parameter V_FRONT_PROCH	=		10;
parameter V_BACK_PROCH	=		33;
parameter V_SYN			=		2;
parameter V_TOTAL		=		V_ACTIVE+V_SYN+V_BACK_PROCH+V_FRONT_PROCH;//525

reg [10:0] hcnt;//counter in one row
reg [9:0] vcnt;//counter in rows

always @(posedge clk or negedge rst_n) begin
	if (!rst_n) begin
		hcnt<=11'h0;
	end
	else if (hcnt==H_TOTAL-1) begin
		hcnt<=11'h0;
	end
	else if(start_send)begin
		hcnt<=hcnt+1'b1;
	end
	else begin
		hcnt<=hcnt;
	end
end
always @(posedge clk or negedge rst_n) begin
	if (!rst_n) begin
		vcnt<=10'h0;	
	end
	else if ((vcnt==V_TOTAL-1) && (hcnt==H_TOTAL-1)) begin
		vcnt<=10'h0;
	end
	else if(hcnt==H_TOTAL-1) begin
		vcnt<=vcnt+1'b1;
	end
	else begin
		vcnt<=vcnt;
	end
end

always @(posedge clk or negedge rst_n) begin
	if(!rst_n) begin 
		one_frame_end<=1'b0;
	end
	else if((vcnt==V_TOTAL-1) && (hcnt==H_TOTAL-1)) begin
		one_frame_end<=1'b1;
	end
	else 
		one_frame_end<= one_frame_end;
end

//syn gen
assign hsyn=( (hcnt<H_SYN +H_FRONT_PROCH) && (hcnt>= H_FRONT_PROCH  )  && start_send );
assign vsyn=( (vcnt<V_SYN +V_FRONT_PROCH) && (vcnt>= V_FRONT_PROCH  )  && start_send );
assign de	=( start_send && (hcnt<H_ACTIVE+H_BACK_PROCH+H_SYN+H_FRONT_PROCH)&& (hcnt>=H_BACK_PROCH+H_SYN+H_FRONT_PROCH)
			&&	(vcnt<V_ACTIVE+V_BACK_PROCH+V_SYN+V_FRONT_PROCH) && (vcnt >= V_BACK_PROCH+V_SYN+V_FRONT_PROCH));

//data stored in ROM
wire rom_en;//read data from rom
wire [7:0] rom_dout;
reg  [18:0] rom_addr_h;
reg  [18:0] rom_addr_w;
//gen rom_addr
assign rom_en=(hcnt<H_ACTIVE+H_BACK_PROCH+H_SYN+H_FRONT_PROCH-1) && (hcnt>=H_BACK_PROCH+H_SYN+H_FRONT_PROCH-1) 
				&&	(vcnt<V_ACTIVE+V_BACK_PROCH+V_SYN+V_FRONT_PROCH-1) && (vcnt >= V_BACK_PROCH+V_SYN+V_FRONT_PROCH-1);


always @(posedge clk or negedge rst_n) begin
	if (!rst_n) begin
		rom_addr_h<=19'h0;		
	end
	else if(rom_addr_h>=V_ACTIVE)
		rom_addr_h<=19'h0;
	else if (rom_en && rom_addr_w>=H_ACTIVE-1) begin
		rom_addr_h<=rom_addr_h+1'b1;
	end
	else begin
		rom_addr_h<=rom_addr_h;
	end
end
always @(posedge clk or negedge rst_n) begin // 640: 256~512
	if (!rst_n) begin
		rom_addr_w<=19'h0;		
	end
	else if(rom_addr_w>=H_ACTIVE)
		rom_addr_w<=19'h0;
	else if (rom_en) begin
		rom_addr_w<=rom_addr_w+1'b1;
	end
	else begin
		rom_addr_w<=rom_addr_w;
	end
end

wire [18:0]rom_addr;
wire rd_en;
assign rom_addr = rom_addr_w[18:3] + (rom_addr_h[18:3]*10'd80) + num*4800;
assign rd_en = rom_en && num<=9;

rom_10_80_60_8 rom(
	// A is write port
	.clka(clk),
	.ena(rd_en),
	// .web(1'b0),
	.addra(rom_addr),
	// .dinb(8'd0),
	.douta(rom_dout) 
);
//data part
always @(posedge clk or negedge rst_n) begin
	if (!rst_n) begin
		dout<=24'hFFFFFF;
	end
	else if (rd_en) begin
		dout<={rom_dout,rom_dout,rom_dout};
	end
	else begin
		dout<=24'hFFFFFF;
	end
end
endmodule